package cmd

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	// Used for flags
	cfgFile     string
	apiURL      string
	apiKey      string
	outputFormat string
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "dataflare",
	Short: "DataFlare CLI",
	Long: `DataFlare CLI is a command-line tool for interacting with DataFlare.

It provides commands for managing workflows, connectors, and other DataFlare resources.`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() error {
	return rootCmd.Execute()
}

func init() {
	cobra.OnInitialize(initConfig)

	// Global flags
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.dataflare.yaml)")
	rootCmd.PersistentFlags().StringVar(&apiURL, "api-url", "", "API URL (default is http://localhost:8080)")
	rootCmd.PersistentFlags().StringVar(&apiKey, "api-key", "", "API key")
	rootCmd.PersistentFlags().StringVar(&outputFormat, "output", "table", "Output format (table, json, yaml)")

	// Bind flags to viper
	viper.BindPFlag("api.url", rootCmd.PersistentFlags().Lookup("api-url"))
	viper.BindPFlag("api.key", rootCmd.PersistentFlags().Lookup("api-key"))
	viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output"))

	// Set default values
	viper.SetDefault("api.url", "http://localhost:8080")
	viper.SetDefault("output", "table")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cfgFile)
	} else {
		// Find home directory.
		home, err := os.UserHomeDir()
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			os.Exit(1)
		}

		// Search config in home directory with name ".dataflare" (without extension).
		viper.AddConfigPath(home)
		viper.SetConfigName(".dataflare")
		viper.SetConfigType("yaml")

		// Also look for config in current directory
		viper.AddConfigPath(".")
	}

	// Read in environment variables that match
	viper.SetEnvPrefix("DATAFLARE")
	viper.AutomaticEnv()

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Fprintf(os.Stderr, "Using config file: %s\n", viper.ConfigFileUsed())
	}

	// Set API URL and key from environment variables if not set in config
	if apiURL == "" {
		apiURL = viper.GetString("api.url")
	}
	if apiKey == "" {
		apiKey = viper.GetString("api.key")
	}
}
